#include "sysinfo.h"
#include "system_settings.h"
#include <fstream>
#include <iostream>
#include <map>
#include <net/if.h>
#include <sstream>
#include <string>
#include <sys/ioctl.h>
#include <sys/statfs.h>
#include <sys/sysinfo.h>
#include <sys/utsname.h>
#include <utils/custom.h>
#include <vector>

namespace settings {

void SystemSettings::UpdateNetDev()
{
    std::ifstream file("/proc/net/dev");
    std::string line;

    netCards.clear();
    // 跳过前两行标题
    std::getline(file, line);
    std::getline(file, line);

    while (std::getline(file, line)) {
        std::istringstream iss(line);
        std::string interface;
        if (!(iss >> interface)) {
            continue;
        }

        interface = interface.substr(0, interface.length() - 1);
        if (interface == "lo") {
            continue;
        }
        // 跳过冒号后的空白字符
        char colon;
        iss >> std::ws >> colon;

        std::string stats_str;
        std::getline(iss, stats_str); // 读取剩余所有统计信息

        NetCard interface_stats;
        std::istringstream stats_iss(stats_str);
        std::string item;
        unsigned long long value;
        std::vector<int32_t *> keys = {&interface_stats.rxPackets, &interface_stats.rxBytes, &interface_stats.rxErrs,
            &interface_stats.rxDrop, &interface_stats.rxFifoErr, &interface_stats.rxFrameErr,
            &interface_stats.rxCompressed, &interface_stats.rxMulticast, &interface_stats.txPackets,
            &interface_stats.txBytes, &interface_stats.txErrs, &interface_stats.txDrop, &interface_stats.txFifoErr,
            &interface_stats.txCollisionErr, &interface_stats.txCarrierErr, &interface_stats.txCompressed};

        interface_stats.ifname = interface;
        for (const auto &key : keys) {
            if (stats_iss >> value) { // 尝试从流中读取一个值
                *key = value;
                // 如果需要，可以跳过分隔符（这里假设是空格或制表符，由std::istringstream自动处理）
            }
        }

        // 获取MAC， IP
        char ipaddr[64];
        char macaddr[64];
        char mask[64];
        char gateway[64];
        sysinfo::GetIfAddr(interface_stats.ifname.c_str(), ipaddr, mask, gateway);
        sysinfo::GetLocalMac(interface_stats.ifname.c_str(), macaddr);
        interface_stats.ipAddr = ipaddr;
        interface_stats.mask = mask;
        interface_stats.MAC = macaddr;
        interface_stats.gateway = gateway;

        netCards.push_back(interface_stats);
    }
}

bool SystemSettings::UpdateSysInfo()
{
    // appVer
    appVer = DAS_VERSION;
    // sysver
    struct utsname un;
    uname(&un);
    sysVer = std::string(un.sysname) + " " + std::string(un.release) + " " + std::string(un.machine);

    // systime
    sysTime = utils::nowtostr();
    return true;
}

bool SystemSettings::UpdateDiskInfo()
{
    struct statfs diskinfo;

    statfs("/", &diskinfo);

    double fused = diskinfo.f_bfree / 1024.0 * diskinfo.f_bsize / 1024.0;
    double ftotal = diskinfo.f_blocks / 1024.0 * diskinfo.f_bsize / 1024.0;
    totalDiskSpace = ftotal;
    freeDiskSpace = fused;
    return true;
}

bool SystemSettings::UpdateMemInfo()
{
    sysinfo::MEM_OCCUPY mc;
    sysinfo::get_mem_occupy(&mc);
    totalMemory = mc.total / 1024.0;
    freeMemory = mc.free / 1024.0;
    return true;
}
} // namespace settings